# SSL修复 - 必须在其他网络库导入之前执行
import ssl_fix

import sys
import json
import requests
import time
import pymysql
from PyQt5.QtCore import QObject, QTimer, pyqtSignal, QThread
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QLabel, QPushButton, QHBoxLayout, QTextEdit, QSpinBox, QFormLayout
from data_crawler import KuaishouAPI
from config import config
from db_connection import DatabaseConnection

class RetryWorker(QThread):
    """后台重试工作线程"""
    
    progress_updated = pyqtSignal(str)
    error_occurred = pyqtSignal(str)
    task_completed = pyqtSignal(int, int)  # success_count, total_checked
    
    def __init__(self, db_config, api_instance, debug_enabled=False):
        super().__init__()
        self.db_config = db_config
        self.api = api_instance
        self.debug_enabled = debug_enabled
        
    def debug_log(self, message):
        if self.debug_enabled:
            self.progress_updated.emit(f"[调试] {message}")
            
    def info_log(self, message):
        self.progress_updated.emit(f"[重试任务] {message}")
        
    def run(self):
        """在工作线程中执行重试任务"""
        self.info_log("开始检查是否存在需要重试的风控失败商品…")
        
        try:
            connection = DatabaseConnection.create_connection(self.db_config)
            
            try:
                with connection.cursor(pymysql.cursors.DictCursor) as cursor:
                    select_sql = "SELECT * FROM ks_goods_rank WHERE deleted = 3 LIMIT 10"
                    cursor.execute(select_sql)
                    records = cursor.fetchall()
                    
                    if not records:
                        self.info_log("本次检查未找到需要处理的风控失败商品")
                        self.task_completed.emit(0, 0)
                        return
                    
                    self.info_log(f"🔄 找到 {len(records)} 个风控失败商品，开始重试...")
                    
                    success_count = 0
                    total_checked = len(records)
                    
                    for record in records:
                        rel_item_id = record['relItemId']
                        item_title = record['itemTitle'][:20] if record['itemTitle'] else '无标题'
                        
                        self.debug_log(f"重试商品: {rel_item_id} ({item_title})")
                        
                        video_list = self.get_product_videos(rel_item_id)
                        
                        if video_list == "RISK_CONTROL_FAILED":
                            self.debug_log(f"❌ 商品 {rel_item_id} 仍然遇到风控拦截")
                            continue
                        elif video_list is not None and len(video_list) > 0:
                            with connection.cursor() as update_cursor:
                                update_sql = """
                                UPDATE ks_goods_rank 
                                SET videoList = %s, deleted = 0
                                WHERE relItemId = %s
                                """
                                video_list_json = json.dumps(video_list, ensure_ascii=False)
                                update_cursor.execute(update_sql, (video_list_json, rel_item_id))
                                connection.commit()
                                
                            success_count += 1
                            self.info_log(f"✅ 商品 {rel_item_id} ({item_title}) 重试成功，获取到 {len(video_list)} 个视频")
                        else:
                            with connection.cursor() as update_cursor:
                                update_sql = """
                                UPDATE ks_goods_rank 
                                SET videoList = %s, deleted = 0
                                WHERE relItemId = %s
                                """
                                update_cursor.execute(update_sql, ('[]', rel_item_id))
                                connection.commit()
                                
                            success_count += 1
                            self.info_log(f"⚠️ 商品 {rel_item_id} ({item_title}) 重试成功，但未获取到视频数据")
                            
                        time.sleep(1)
                        
                    if success_count > 0:
                        self.info_log(f"📊 本次重试完成，成功处理 {success_count}/{total_checked} 个商品")
                    else:
                        self.info_log("本次重试未成功处理任何商品")
                    
                    self.task_completed.emit(success_count, total_checked)
                        
            finally:
                connection.close()
                
        except Exception as e:
            self.error_occurred.emit(f"风控重试任务出错: {str(e)}")
            self.task_completed.emit(0, 0)
            
    def get_product_videos(self, rel_item_id):
        """获取商品的视频列表"""
        try:
            base_url = "https://app.kwaixiaodian.com/gateway/distribute/match/selection/decision/app/info"
            
            headers_with_cookie = self.api.headers.copy()
            current_cookie = self.api.get_current_cookie() if self.api.cookies else ""
            headers_with_cookie["Cookie"] = current_cookie
            
            payload = {
                "relItemId": rel_item_id,
                "sceneCode": "selection_decision",
                "themeSceneId": "",
                "relSceneCode": "CPS"
            }
            
            self.debug_log(f"重试请求地址: {base_url}")
            self.debug_log(f"重试请求参数: {json.dumps(payload, ensure_ascii=False)}")
            
            response = requests.post(base_url, headers=headers_with_cookie, json=payload, timeout=15)
            self.debug_log(f"重试响应状态码: {response.status_code}")
            
            if response.status_code == 200:
                data = response.json()
                self.debug_log(f"重试响应数据: {json.dumps(data, ensure_ascii=False)[:200]}...")
                
                if data.get("result") == 2 and "风控拦截" in data.get("msg", ""):
                    self.debug_log(f"商品 {rel_item_id} 仍然遇到风控拦截")
                    return "RISK_CONTROL_FAILED"
                
                video_list = self.parse_video_list_from_data(data)
                return video_list
            else:
                self.debug_log(f"重试获取商品 {rel_item_id} 视频列表失败，状态码: {response.status_code}")
                return []
                
        except Exception as e:
            self.debug_log(f"重试获取商品 {rel_item_id} 视频列表时出错: {e}")
            return []
            
    def parse_video_list_from_data(self, data):
        """从 API 返回的数据中解析视频列表信息"""
        try:
            video_list = []
            data_section = data.get("data", {})
            data_items = data_section.get("data", {})
            
            for key, value in data_items.items():
                if key.startswith("mtp_videoList_") and "fields" in value:
                    video_fields = value["fields"]
                    videos = video_fields.get("videoList", [])
                    self.debug_log(f"找到视频列表字段，包含 {len(videos)} 个视频")
                    
                    for video in videos:
                        video_url = video.get('videoUrl', '')
                        gmv_of_90 = video.get('gmvOf90', 0)
                        if video_url:
                            video_list.append({
                                'url': video_url,
                                'gmv': gmv_of_90
                            })
                    break
                    
            video_list.sort(key=lambda x: x['gmv'], reverse=True)
            result = [video['url'] for video in video_list[:5]]
            return result
        except Exception as e:
            self.debug_log(f"解析视频列表数据时出错: {e}")
            return []


class RiskControlRetryManager(QObject):
    """风控失败商品重试任务管理器"""
    
    progress_updated = pyqtSignal(str)
    task_status_changed = pyqtSignal(bool)  # True表示启动，False表示停止
    error_occurred = pyqtSignal(str)
    
    def __init__(self, db_config, api_instance):
        super().__init__()
        self.db_config = db_config
        self.api = api_instance
        self.running = False
        self.timer = QTimer()
        self.timer.timeout.connect(self.trigger_check)
        self.debug_enabled = False
        self.processed_count = 0  # 处理成功的商品数
        self.total_processed = 0  # 总共检查的商品数
        self.check_interval = 10  # 默认检查间隔为10秒
        self.worker = None  # 当前工作线程
        
    def set_debug_enabled(self, enabled):
        """设置调试日志是否启用"""
        self.debug_enabled = enabled
        
    def debug_log(self, message):
        """调试日志输出"""
        if self.debug_enabled:
            self.progress_updated.emit(f"[调试] {message}")
            
    def info_log(self, message):
        """信息日志输出（始终显示）"""
        self.progress_updated.emit(f"[重试任务] {message}")
            
    def set_check_interval(self, seconds):
        """设置检查间隔时间（秒）"""
        self.check_interval = seconds
        if self.running:
            # 如果任务正在运行，重启定时器以应用新的间隔
            self.timer.stop()
            self.timer.start(self.check_interval * 1000)
            self.info_log(f"⚙️ 检查间隔已更新为 {self.check_interval} 秒")
    
    def get_check_interval(self):
        """获取当前检查间隔时间"""
        return self.check_interval
            
    def start_task(self):
        """启动后台重试任务"""
        if not self.running:
            self.running = True
            self.processed_count = 0
            self.total_processed = 0
            self.timer.start(self.check_interval * 1000)  # 使用配置的间隔时间
            self.info_log(f"✅ 风控失败商品重试任务已启动，每 {self.check_interval} 秒检查一次")
            self.task_status_changed.emit(True)
            # 立即触发第一次检查
            QTimer.singleShot(1000, self.trigger_check)
            
    def stop_task(self):
        """停止后台重试任务"""
        if self.running:
            self.running = False
            self.timer.stop()
            self.info_log(f"⏹️ 风控重试任务已停止，累计处理成功 {self.processed_count} 个商品（总检查 {self.total_processed} 个）")
            self.task_status_changed.emit(False)
            
    def is_running(self):
        """检查任务是否正在运行"""
        return self.running
    
    def trigger_check(self):
        """触发检查任务（非阻塞）"""
        if not self.running:
            return
        
        # 如果上一个工作线程还在运行，跳过本次检查
        if self.worker and self.worker.isRunning():
            self.debug_log("上一个检查任务尚未完成，跳过本次检查")
            return
        
        # 创建新的工作线程
        self.worker = RetryWorker(self.db_config, self.api, self.debug_enabled)
        self.worker.progress_updated.connect(self.progress_updated.emit)
        self.worker.error_occurred.connect(self.error_occurred.emit)
        self.worker.task_completed.connect(self.on_task_completed)
        self.worker.start()
    
    def on_task_completed(self, success_count, total_checked):
        """任务完成回调"""
        self.processed_count += success_count
        self.total_processed += total_checked

class RetryTaskControlDialog(QDialog):
    """重试任务控制对话框"""
    
    def __init__(self, retry_manager, parent=None):
        super().__init__(parent)
        self.retry_manager = retry_manager
        self.setWindowTitle("风控重试任务控制")
        self.setModal(False)
        self.resize(600, 400)
        self.setup_ui()
        
        # 连接信号
        self.retry_manager.progress_updated.connect(self.add_log)
        self.retry_manager.task_status_changed.connect(self.update_button_state)
        self.retry_manager.error_occurred.connect(self.add_error_log)
        
    def setup_ui(self):
        layout = QVBoxLayout(self)
        
        # 状态说明
        status_label = QLabel("风控失败商品自动重试任务")
        status_label.setStyleSheet("""
            QLabel {
                font-size: 16px;
                font-weight: bold;
                color: #333;
                padding: 10px;
                background-color: #f0f8ff;
                border-radius: 5px;
                margin-bottom: 10px;
            }
        """)
        layout.addWidget(status_label)
        
        # 配置区域
        config_layout = QFormLayout()
        
        # 检查间隔配置
        self.interval_spinbox = QSpinBox()
        self.interval_spinbox.setRange(5, 300)  # 5秒到300秒（5分钟）
        self.interval_spinbox.setValue(self.retry_manager.get_check_interval())
        self.interval_spinbox.setSuffix(" 秒")
        self.interval_spinbox.valueChanged.connect(self.on_interval_changed)
        self.interval_spinbox.setStyleSheet("""
            QSpinBox {
                padding: 5px;
                border: 1px solid #ccc;
                border-radius: 3px;
                font-size: 12px;
            }
        """)
        
        interval_label = QLabel("检查间隔:")
        interval_label.setStyleSheet("font-weight: bold; color: #333;")
        config_layout.addRow(interval_label, self.interval_spinbox)
        
        layout.addLayout(config_layout)
        
        # 功能说明
        desc_label = QLabel(f"• 每 {self.retry_manager.get_check_interval()} 秒自动检查数据库中deleted=3的风控失败商品\n• 重新请求视频API，成功获取则更新为deleted=0\n• 可实时查看处理进度和结果\n• 可自定义检查时间间隔（5-300秒）")
        desc_label.setStyleSheet("""
            QLabel {
                color: #666;
                padding: 5px;
                line-height: 1.5;
            }
        """)
        layout.addWidget(desc_label)
        
        # 控制按钮
        button_layout = QHBoxLayout()
        
        self.start_btn = QPushButton("启动重试任务")
        self.start_btn.clicked.connect(self.start_task)
        self.start_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                padding: 8px 16px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #218838;
            }
            QPushButton:disabled {
                background-color: #6c757d;
            }
        """)
        
        self.stop_btn = QPushButton("停止重试任务")
        self.stop_btn.clicked.connect(self.stop_task)
        self.stop_btn.setStyleSheet("""
            QPushButton {
                background-color: #dc3545;
                color: white;
                border: none;
                padding: 8px 16px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #c82333;
            }
            QPushButton:disabled {
                background-color: #6c757d;
            }
        """)
        
        self.clear_btn = QPushButton("清除日志")
        self.clear_btn.clicked.connect(self.clear_log)
        self.clear_btn.setStyleSheet("""
            QPushButton {
                background-color: #6c757d;
                color: white;
                border: none;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #5a6268;
            }
        """)
        
        button_layout.addWidget(self.start_btn)
        button_layout.addWidget(self.stop_btn)
        button_layout.addWidget(self.clear_btn)
        button_layout.addStretch()
        
        layout.addLayout(button_layout)
        
        # 日志显示区域
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setStyleSheet("""
            QTextEdit {
                background-color: #2b2b2b;
                color: #ffffff;
                font-family: 'Consolas', 'Monaco', monospace;
                font-size: 12px;
                border: 1px solid #555;
                border-radius: 4px;
            }
        """)
        layout.addWidget(self.log_text)
        
        # 初始化按钮状态
        self.update_button_state(self.retry_manager.is_running())
        
    def on_interval_changed(self, value):
        """检查间隔改变时的处理"""
        self.retry_manager.set_check_interval(value)
        # 更新功能说明中的间隔时间
        self.update_description_label()
        
    def start_task(self):
        """启动重试任务"""
        self.retry_manager.start_task()
        
    def stop_task(self):
        """停止重试任务"""
        self.retry_manager.stop_task()
        
    def clear_log(self):
        """清除日志"""
        self.log_text.clear()
        
    def add_log(self, message):
        """添加日志"""
        from datetime import datetime
        timestamp = datetime.now().strftime("%H:%M:%S")
        
        # 根据消息类型设置颜色
        if "[调试]" in message:
            color = "#888888"
        elif "[重试任务]" in message:
            color = "#00ff00"
        elif "✅" in message:
            color = "#00ff00"
        elif "❌" in message:
            color = "#ff6b6b"
        elif "⚠️" in message:
            color = "#ffaa00"
        elif "🔄" in message:
            color = "#00bfff"
        elif "📊" in message:
            color = "#ff6b35"
        else:
            color = "#ffffff"
            
        log_entry = f'<span style="color: {color};">[{timestamp}] {message}</span>'
        self.log_text.append(log_entry)
        
        # 滚动到最新日志
        cursor = self.log_text.textCursor()
        cursor.movePosition(cursor.End)
        self.log_text.setTextCursor(cursor)
        
    def add_error_log(self, message):
        """添加错误日志"""
        self.add_log(f"❌ 错误: {message}")
        
    def update_description_label(self):
        """更新功能说明标签"""
        # 找到功能说明标签并更新文本
        layout = self.layout()
        if layout is not None:
            for i in range(layout.count()):
                item = layout.itemAt(i)
                if item is not None:
                    widget = item.widget()
                    if isinstance(widget, QLabel) and "自动检查数据库" in widget.text():
                        widget.setText(f"• 每 {self.retry_manager.get_check_interval()} 秒自动检查数据库中deleted=3的风控失败商品\n• 重新请求视频API，成功获取则更新为deleted=0\n• 可实时查看处理进度和结果\n• 可自定义检查时间间隔（5-300秒）")
                        break
    
    def update_button_state(self, is_running):
        """更新按钮状态"""
        self.start_btn.setEnabled(not is_running)
        self.stop_btn.setEnabled(is_running)
        # 运行时禁用间隔配置，避免频繁修改
        self.interval_spinbox.setEnabled(not is_running)